// src/components/message.tsx
import dynamic from "next/dynamic";
import {format, isToday, isYesterday} from "date-fns";
import Hint from "@/components/social/hint";
import {Avatar, AvatarFallback, AvatarImage} from "@/components/ui/avatar";
import Thumbnail from "@/components/social/thumbnail";
import Toolbar from "@/components/social/Toolbar";
import {useUpdateMessage} from "@/features/messages/api/use-update-message";
import {toast} from "sonner";
import {cn} from "@/lib/utils";
import {useRemoveMessage} from "@/features/messages/api/use-remove-message";
import useConfirm from "@/hooks/social/use-confirm";
import {useToggleReaction} from "@/features/reactions/api/use-toggle-reactions";
import Reactions from "@/components/social/reactions";
import {usePanel} from "@/hooks/social/use-panel";
import ThreadBar from "@/components/social/thread-bar";
import {useEffect, useState} from "react";
import {useGetMessages} from "@/features/messages/api/use-get-messages";
import {useChannelId} from "@/hooks/social/use-channel-id";

// 初始情况不需要该组件, 当用到再加载
const Renderer =
    dynamic(() => import(`@/components/social/renderer`),
        {ssr: false} // 服务器端不需要该组件
    )
const Editor =
    dynamic(() => import(`@/components/social/editor`),
        {ssr: false}
    )

const formatFullTime = (date: Date) => {
    return `${isToday(date) ? 'Today'
        : isYesterday(date) ? 'Yesterday'
            : format(date, 'MMM d, yyyy')} at ${format(date, 'h:mm:ss a')}`
}

interface Props {
    id: string
    memberId: string
    authorImage?: string
    authorName?: string
    isAuthor: boolean
    reactions: {
        id: string
        count: number
        memberIds: string[]
        value: string
    }[]
    body: string
    image: string | null | undefined
    createdAt: number
    updatedAt: number
    isEditing: boolean
    isCompact?: boolean
    setEditingId: (id: string | null) => void
    hideThreadButton?: boolean
    threadCount?: number
    threadImage?: string
    threadName?: string
    threadTimestamp?: number
    // threadTimestamp?: string
}

const Message = ({
                     id, isAuthor, memberId, authorImage, authorName = 'Member', reactions,
                     body, image, createdAt, updatedAt, isEditing, isCompact, setEditingId,
                     threadName, threadTimestamp, threadCount, threadImage, hideThreadButton
                 }: Props) => {
    const {parentMessageId, onOpenProfile, onOpenMessage, onClose} = usePanel()
    console.log('message component', parentMessageId)

    const [ConfirmDialog, confirm] = useConfirm(
        "Delete message",
        "Are you sure you want to delete this message? This cannot be undone",
    )

    const {mutate: updateMessage, isPending: isUpdatingMessage} = useUpdateMessage();
    const {mutate: removeMessage, isPending: isRemovingMessage} = useRemoveMessage();
    const {mutate: toggleReaction, isPending: isTogglingReaction} = useToggleReaction()
    const isPending = isUpdatingMessage || isRemovingMessage || isTogglingReaction

    const handleUpdate = ({body}: { body: string }) => {
        updateMessage({
            id, body
        }, {
            onSuccess() {
                toast.success("Message updated")
                setEditingId(null)
            },
            onError() {
                toast.error("Failed to update message")
            }
        })
    }

    const handleDelete = async () => {
        const ok = await confirm()
        if (!ok) return

        removeMessage({id}, {
            onSuccess() {
                toast.success(`Message deleted`)

                if (parentMessageId === id) {
                    onClose()
                }
            },
            onError() {
                toast.error(`Failed to delete message`)
            }
        })
    }

    const handleReaction = (value: string) => {
        toggleReaction({messageId: id, value, memberId}, {
            onSuccess() {
                toast.success(`toggle reaction success`)
            },
            onError() {
                toast.error(`Failed to toggle reaction`)
            }
        })
    }

    // 获取该信息的子集
    // const [reply, setReply] = useState()
    // const channelId = useChannelId()
    // useEffect(() => {
    //     (async () => {
    //         const {data} = await useGetMessages({
    //             channelId, parentMessageId: id
    //         })
    //         setReply(data)
    //     })()
    // }, [])

    if (isCompact) { // 紧凑模式
        return (
            <>
                <ConfirmDialog/>
                <div className={cn(
                    `flex flex-col gap-2 p-1.5 px-5 hover:bg-gray-100/60 group relative`,
                    isEditing && `bg-[#f2c74433] hover:bg-[#f2c74433]`,
                    isRemovingMessage &&
                    `bg-rose-500/50 transform transition-all scale-y-0 origin-bottom duration-200`
                )}>
                    <div className={`flex items-start gap-2`}>
                        <Hint label={formatFullTime(new Date(createdAt))}>
                            <button
                                className={`text-xs text-muted-foreground opacity-0 group-hover:opacity-100 
                    w-[40px] leading-[22px] text-center hover:underline`}>
                                {format(new Date(createdAt), 'hh:mm')}
                            </button>
                        </Hint>
                        {isEditing ? (
                            <div className={`w-full h-full`}>
                                <Editor
                                    onSubmit={handleUpdate}
                                    disabled={isPending}
                                    defaultValue={JSON.parse(body)}
                                    onCancel={() => setEditingId(null)}
                                    variant={'update'}
                                />
                            </div>
                        ) : (
                            <div className={`flex flex-col w-full`}>
                                <Renderer value={body}/>
                                <Thumbnail url={image}/>
                                {(updatedAt && updatedAt !== createdAt) ? (
                                    <span className={`text-xs text-muted-foreground`}>(edited)</span>
                                ) : null}
                                {reactions && reactions.length !== 0 && <Reactions
                                    // @ts-ignore
                                    data={reactions}
                                    onChange={handleReaction}
                                />}
                                {<ThreadBar
                                    name={''}
                                    // count={reply[0].threadCount}
                                    count={threadCount}
                                    image={''}
                                    // @ts-ignore
                                    // timestamp={parseInt(reply[0].threadTimestamp!)!}
                                    timestamp={parseInt(threadTimestamp!)!}
                                    onClick={() => onOpenMessage(id)}
                                />}
                            </div>
                        )}
                    </div>
                    {!isEditing && (
                        <Toolbar
                            isAuthor={isAuthor}
                            isPending={isPending}
                            handleEdit={() => setEditingId(id)}
                            handleThread={() => onOpenMessage(id)}
                            handleDelete={handleDelete}
                            hideThreadButton={hideThreadButton!}
                            handleReaction={handleReaction}
                        />
                    )}
                </div>
            </>
        );
    }

    const avatarFallback = authorName?.charAt(0).toUpperCase()

    return (
        <>
            <ConfirmDialog/>
            <div className={cn(
                `flex flex-col gap-2 p-1.5 px-5 hover:bg-gray-100/60 group relative`,
                isEditing && `bg-[#f2c74433] hover:bg-[#f2c74433]`
            )}>
                <div className={`flex items-start gap-2`}>
                    <button
                        // 点击用户头像打开用户信息面版
                        onClick={
                            () => onOpenProfile(memberId)
                            // () => onOpenProfile('e55214c4-9f0c-427a-a9f5-283573575a83')
                        }
                    >
                        <Avatar className={`rounded-md`}>
                            <AvatarImage className={`rounded-md object-cover`} src={authorImage}/>
                            <AvatarFallback className={`rounded-md bg-sky-500 text-white text-xs`}>
                                {avatarFallback}
                            </AvatarFallback>
                        </Avatar>
                    </button>
                    {isEditing ? (
                        <div className={`w-full h-full`}>
                            <Editor
                                onSubmit={handleUpdate}
                                disabled={isPending}
                                defaultValue={JSON.parse(body)}
                                onCancel={() => setEditingId(null)}
                                variant={'update'}
                            />
                        </div>
                    ) : (
                        <div className={`flex flex-col w-full overflow-hidden`}>
                            <div className={`text-sm`}>
                                <button
                                    onClick={() => onOpenProfile(memberId)}
                                    // onClick={() => onOpenProfile('e55214c4-9f0c-427a-a9f5-283573575a83')}
                                    className={`font-bold text-primary hover:underline`}
                                >
                                    {authorName}
                                </button>
                                <span>&nbsp;&nbsp;</span>
                                <Hint label={formatFullTime(new Date(createdAt))}>
                                    <button className={`text-xs text-muted-foreground hover:underline`}>
                                        {format(new Date(createdAt), 'hh:mm a')}
                                    </button>
                                </Hint>
                            </div>
                            <Renderer value={body}/>
                            <Thumbnail url={image}/>
                            {(updatedAt && updatedAt !== createdAt) ? (
                                <span className={`text-xs text-muted-foreground`}>(edited)</span>
                            ) : null}
                            {reactions && reactions.length !== 0 && <Reactions
                                // @ts-ignore
                                data={reactions}
                                onChange={handleReaction}
                            />}
                            {<ThreadBar
                                name={''}
                                // count={reply[0].threadCount}
                                count={threadCount}
                                image={''}
                                // @ts-ignore
                                // timestamp={parseInt(reply[0].threadTimestamp!)!}
                                timestamp={parseInt(threadTimestamp!)!}
                                onClick={() => onOpenMessage(id)}
                            />}
                        </div>
                    )}
                </div>
                {!isEditing && (
                    <Toolbar
                        isAuthor={isAuthor}
                        isPending={isPending}
                        handleEdit={() => setEditingId(id)}
                        handleThread={() => onOpenMessage(id)}
                        handleDelete={handleDelete}
                        hideThreadButton={hideThreadButton!}
                        handleReaction={handleReaction}
                    />
                )}
            </div>
        </>
    );
};

export default Message;